const jwt = require('../utils/jwt');
const User = require('../models/User');
const { unauthorizedResponse, forbiddenResponse, internalErrorResponse } = require('../utils/response');
const logger = require('../utils/logger');

/**
 * 验证JWT令牌中间件
 */
const authenticateToken = async (req, res, next) => {
  try {
    logger.info('认证中间件开始处理:', {
      path: req.path,
      method: req.method,
      hasAuthHeader: !!req.headers.authorization
    });

    const token = jwt.extractTokenFromHeader(req);
    
    if (!token) {
      logger.info('访问令牌缺失');
      return unauthorizedResponse(res, '访问令牌缺失');
    }

    // 验证令牌
    const decoded = jwt.verifyAccessToken(token);
    logger.info('令牌验证成功:', { userId: decoded.userId });
    
    // 查找用户
    const user = await User.findById(decoded.userId).select('-password');
    
    if (!user) {
      logger.info('用户不存在:', { userId: decoded.userId });
      return unauthorizedResponse(res, '用户不存在');
    }

    logger.info('用户验证成功:', {
      userId: user._id,
      username: user.username,
      role: user.role,
      status: user.status
    });

    if (user.status !== 'active') {
      logger.info('用户账户状态检查失败:', {
        userId: user._id,
        username: user.username,
        currentStatus: user.status,
        expectedStatus: 'active'
      });
      return forbiddenResponse(res, '账户已被禁用');
    }

    // 将用户信息和令牌信息添加到请求对象
    req.user = user;
    req.token = token;
    req.tokenPayload = decoded;

    logger.info('认证中间件完成，继续下一个中间件');
    next();
  } catch (error) {
    if (error.name === 'JsonWebTokenError') {
      return unauthorizedResponse(res, '无效的访问令牌');
    }
    
    if (error.name === 'TokenExpiredError') {
      return unauthorizedResponse(res, '访问令牌已过期');
    }

    logger.error('令牌验证中间件错误:', {
      error: error.message,
      stack: error.stack
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 可选认证中间件（用户可能未登录的接口）
 */
const optionalAuth = async (req, res, next) => {
  try {
    const token = jwt.extractTokenFromHeader(req);
    
    if (token) {
      try {
        const decoded = jwt.verifyAccessToken(token);
        const user = await User.findById(decoded.userId).select('-password');
        
        if (user && user.status === 'active') {
          req.user = user;
          req.token = token;
          req.tokenPayload = decoded;
        }
      } catch (error) {
        // 忽略令牌验证错误，继续处理请求
        logger.debug('可选认证令牌验证失败:', { error: error.message });
      }
    }

    next();
  } catch (error) {
    logger.error('可选认证中间件错误:', {
      error: error.message,
      stack: error.stack
    });

    // 不阻止请求继续处理
    next();
  }
};

/**
 * 角色权限验证中间件
 * @param {string[]} allowedRoles - 允许的角色数组
 */
const requireRoles = (allowedRoles) => {
  return (req, res, next) => {
    if (!req.user) {
      return unauthorizedResponse(res, '请先登录');
    }

    if (!allowedRoles.includes(req.user.role)) {
      return forbiddenResponse(res, '权限不足，需要以下角色之一: ' + allowedRoles.join(', '));
    }

    next();
  };
};

/**
 * 管理员权限验证中间件
 */
const requireAdmin = requireRoles(['admin']);

/**
 * 茶农权限验证中间件
 */
const requireFarmer = requireRoles(['farmer', 'admin']);

/**
 * 物流方权限验证中间件
 */
const requireLogistics = requireRoles(['logistics', 'admin']);

/**
 * 商家权限验证中间件
 */
const requireMerchant = requireRoles(['merchant', 'admin']);

/**
 * 特定用户验证中间件（用户只能操作自己的资源）
 */
const requireSelfOrAdmin = (req, res, next) => {
  if (!req.user) {
    return unauthorizedResponse(res, '请先登录');
  }

  const targetUserId = req.params.userId || req.params.id;
  const isAdmin = req.user.role === 'admin';
  const isSelf = req.user._id.toString() === targetUserId;

  if (!isAdmin && !isSelf) {
    return forbiddenResponse(res, '只能操作自己的资源');
  }

  next();
};

/**
 * 资源所有者验证中间件
 * @param {string} resourceModel - 资源模型名称
 * @param {string} ownerField - 所有者字段名称
 */
const requireResourceOwner = (resourceModel, ownerField = 'createdBy') => {
  return async (req, res, next) => {
    try {
      if (!req.user) {
        return unauthorizedResponse(res, '请先登录');
      }

      const resourceId = req.params.id;
      const Model = require(`../models/${resourceModel}`);
      
      const resource = await Model.findById(resourceId);
      
      if (!resource) {
        return res.status(404).json({
          success: false,
          message: '资源不存在'
        });
      }

      const isAdmin = req.user.role === 'admin';
      const isOwner = resource[ownerField].toString() === req.user._id.toString();

      if (!isAdmin && !isOwner) {
        return forbiddenResponse(res, '只能操作自己创建的资源');
      }

      req.resource = resource;
      next();
    } catch (error) {
      logger.error('资源所有者验证失败:', {
        error: error.message,
        resourceModel,
        ownerField,
        resourceId: req.params.id,
        userId: req.user?._id
      });

      return internalErrorResponse(res, error);
    }
  };
};

/**
 * API密钥验证中间件（用于服务间调用）
 */
const authenticateApiKey = (req, res, next) => {
  const apiKey = req.headers['x-api-key'];
  const validApiKey = process.env.API_KEY;

  if (!validApiKey) {
    logger.warn('API密钥未配置');
    return next();
  }

  if (!apiKey || apiKey !== validApiKey) {
    return unauthorizedResponse(res, '无效的API密钥');
  }

  next();
};

/**
 * 账户锁定检查中间件
 */
const checkAccountLock = async (req, res, next) => {
  try {
    const { email } = req.body;
    
    if (email) {
      const user = await User.findByEmail(email);
      
      if (user && user.isAccountLocked()) {
        return forbiddenResponse(res, '账户已被锁定，请稍后再试');
      }
    }

    next();
  } catch (error) {
    logger.error('账户锁定检查失败:', { error: error.message });
    next();
  }
};

module.exports = {
  authenticateToken,
  optionalAuth,
  requireRoles,
  requireAdmin,
  requireFarmer,
  requireLogistics,
  requireMerchant,
  requireSelfOrAdmin,
  requireResourceOwner,
  authenticateApiKey,
  checkAccountLock
};